import pyautogui
import time
import os
import pyperclip
import keyboard
import threading
import json
from tkinter import filedialog, messagebox

class OperationSequenceManager:
    """操作序列管理器 - 用于管理操作序列的创建、保存和加载"""
    
    def __init__(self):
        self.operation_sequence = []
        self.config_window = None
    
    def create_operation_sequence(self):
        """创建操作序列并返回序列对象"""
        if self.config_window and self.config_window.root.winfo_exists():
            # 如果配置窗口已经存在，将其置顶
            self.config_window.root.lift()
            self.config_window.root.focus_force()
            return self.operation_sequence
        
        # 创建配置窗口
        from config_window import EnhancedOperationConfigWindow
        self.config_window = EnhancedOperationConfigWindow(self)
        self.config_window.root.mainloop()
        
        return self.operation_sequence
    
    def get_operation_sequence(self):
        """获取当前操作序列"""
        return self.operation_sequence.copy()  # 返回副本避免外部修改
    
    def set_operation_sequence(self, sequence):
        """设置操作序列"""
        if isinstance(sequence, list):
            self.operation_sequence = sequence
        else:
            raise ValueError("操作序列必须是列表类型")
    
    def save_sequence_to_file(self, filename=None):
        """保存操作序列到文件"""
        if not self.operation_sequence:
            raise ValueError("没有操作序列可保存")
        
        if filename is None:
            filename = filedialog.asksaveasfilename(
                defaultextension=".json",
                filetypes=[("JSON files", "*.json"), ("All files", "*.*")],
                title="保存操作序列配置"
            )
            if not filename:
                return False
        
        try:
            with open(filename, 'w', encoding='utf-8') as f:
                json.dump(self.operation_sequence, f, ensure_ascii=False, indent=2)
            return True
        except Exception as e:
            raise Exception(f"保存失败: {e}")
    
    def load_sequence_from_file(self, filename=None):
        """从文件加载操作序列"""
        if filename is None:
            filename = filedialog.askopenfilename(
                filetypes=[("JSON files", "*.json"), ("All files", "*.*")],
                title="加载操作序列配置"
            )
            if not filename:
                return False
        
        try:
            with open(filename, 'r', encoding='utf-8') as f:
                sequence = json.load(f)
            
            # 验证数据结构
            if not isinstance(sequence, list):
                raise ValueError("配置文件格式错误：应该是一个操作序列列表")
            
            for i, op in enumerate(sequence):
                if not isinstance(op, dict) or 'type' not in op:
                    raise ValueError(f"操作 {i+1} 格式错误")
            
            self.operation_sequence = sequence
            return True
        except Exception as e:
            raise Exception(f"加载失败: {e}")
    
    def execute_sequence(self, txt_path=None, callback=None, mode="auto"):
        """执行操作序列
        Args:
            txt_path: 文本文件路径，包含要处理的内容
            callback: 状态回调函数
            mode: 执行模式 - "auto"(自动判断), "click_only"(仅点击), "text_loop"(文本遍历), "preset_text"(预设文本)
        """
        if not self.operation_sequence:
            raise ValueError("没有操作序列可执行")
        
        exit_flag = False
        
        def _check_for_exit():
            nonlocal exit_flag
            while not exit_flag:
                if keyboard.is_pressed('F2'):
                    exit_flag = True
                    if callback:
                        callback("检测到F2键，正在退出...")
                    break
                time.sleep(0.1)
        
        # 启动键盘监听线程
        keyboard_thread = threading.Thread(target=_check_for_exit, daemon=True)
        keyboard_thread.start()
        
        # 根据模式确定执行策略
        if mode == "auto":
            # 自动判断：如果有文本文件且不为空，使用文本遍历模式，否则使用仅点击模式
            if txt_path and os.path.exists(txt_path):
                with open(txt_path, 'r', encoding='utf-8') as file:
                    lines = [line.strip() for line in file.readlines() if line.strip()]
                mode = "text_loop" if lines else "click_only"
            else:
                mode = "click_only"
        
        # 准备执行内容
        if mode == "text_loop":
            # 文本遍历模式：读取文本文件并逐行处理
            if not txt_path or not os.path.exists(txt_path):
                raise ValueError("文本遍历模式需要有效的文本文件路径")
            
            with open(txt_path, 'r', encoding='utf-8') as file:
                contents = [line.strip() for line in file.readlines() if line.strip()]
            
            if callback:
                callback(f"文本遍历模式：共{len(contents)}项内容待处理")
                
        elif mode == "click_only":
            # 仅点击模式：执行一次操作序列，不处理文本
            contents = [""]
            if callback:
                callback("仅点击模式：执行一次操作序列")
                
        elif mode == "preset_text":
            # 预设文本模式：使用操作中预设的文本
            contents = [""]
            if callback:
                callback("预设文本模式：使用操作中预设的文本")
        else:
            raise ValueError(f"不支持的模式: {mode}")
        
        # 遍历内容（或执行一次）
        for i, content in enumerate(contents):
            if exit_flag:
                if callback:
                    callback("用户请求退出脚本")
                break
                
            current_status = f"正在处理第{i+1}/{len(contents)}项"
            if mode == "text_loop" and content:
                current_status += f": {content[:20]}..."
            if callback:
                callback(current_status)
            
            # 执行操作序列
            for j, operation in enumerate(self.operation_sequence):
                if exit_flag:
                    break
                    
                op_status = f"执行操作 {j+1}: {operation['description']}"
                if callback:
                    callback(op_status)
                
                try:
                    if operation["type"] == "click":
                        pyautogui.click(operation["x"], operation["y"])
                        
                    elif operation["type"] == "scroll":
                        pyautogui.moveTo(operation["x"], operation["y"])
                        pyautogui.scroll(operation["scroll_amount"])
                        
                    elif operation["type"] == "keyboard":
                        # 根据模式处理键盘操作
                        if mode == "text_loop" and content:
                        # 文本遍历模式：使用当前行的内容
                            pyperclip.copy(content)
                            pyautogui.hotkey('ctrl', 'v')
                        elif mode == "preset_text" and "text" in operation:
                            # 预设文本模式：使用操作中预设的文本
                            pyperclip.copy(operation["text"])
                            pyautogui.hotkey('ctrl', 'v')
                        elif "text" in operation:
                            # 其他模式：使用预设文本（如果有）
                            pyautogui.write(operation["text"])
                        else:
                            # 仅点击模式：跳过文本输入
                            if callback:
                                callback("跳过键盘操作（仅点击模式）")
                            continue
                    
                    # 操作延迟
                    time.sleep(operation["delay"])
                    
                    # 操作后延迟
                    post_delay = operation.get("post_delay", 0.5)
                    if post_delay > 0:
                        time.sleep(post_delay)
                    
                except Exception as e:
                    error_msg = f"执行操作时出错: {e}"
                    if callback:
                        callback(error_msg)
                    continue
            
            if not exit_flag:
                if callback:
                    callback("所有操作执行完成!")
        
        return not exit_flag